package com.yami.shop.common.util;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpRequest;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.yami.shop.common.config.Constant;
import com.yami.shop.common.exception.YamiShopBindException;
import com.yami.shop.common.response.ResponseEnum;
import lombok.SneakyThrows;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestClientException;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.util.*;

/**
 *
 * @ClassName: DataWebServiceImpl.java
 * @Description: 从第三方服务获取数据接口实现
 * @Author: houhou
 * @Date: 2019年5月8日 上午9:17:55
 * @History 修改描述
 */
@Service
public class DataWebNewServiceImpl implements DataWebService {

	// 日志记录
	private static final Logger logger = LoggerFactory.getLogger(DataWebNewServiceImpl.class);
	private static final String key = "jykFkVoCv1O2Le06";


	private static String paramsConvertUrl(Map<String, String> params) {
		StringBuilder urlParams = new StringBuilder("?");
		Set<Map.Entry<String, String>> entries = params.entrySet();
		for (Map.Entry<String, String> entry : params.entrySet()) {
			if(!Objects.isNull(entry.getValue())){
				urlParams.append(entry.getKey()).append("=").append(entry.getValue()).append("&");
			}
		}
		String urlParamsStr = urlParams.toString();
		return urlParamsStr.substring(0, urlParamsStr.length()-1);
	}


	/**
	 *
	 * @Description: 组装外层通用参数
	 * @param channelCode 渠道编码
	 * @param data 待传输的加密数据
	 * @return 参数map
	 */
	@SneakyThrows
	public MultiValueMap<String, Object> setRequestMapParams(String channelCode, String data) {
		long timeStamp = System.currentTimeMillis();
		// 组装外层通用参数
		MultiValueMap<String, Object> multiValueMap = new LinkedMultiValueMap<String, Object>();
		multiValueMap.add("channelCode", channelCode);
		multiValueMap.add("data", ParamSignUtil.paramEncode(data, "dtc"));
		multiValueMap.add("timeStamp", timeStamp + "");
		return multiValueMap;
	}

	@Override
	public JSONObject hutoolGetWebService(String url, Map<String, String> params,String dtcName,String password) {
		try {
			String paramsStr = setGetRequestMapParams(params,dtcName,password);
			logger.info("从第三方Get获取数据,请求地址是:{},有效参数是:{},加密封装后:{}",url,Json.toJsonString(params),paramsStr);
			String result = HttpRequest.get(url+paramsStr).setConnectionTimeout(60000).execute().body();
			logger.info("从第三方Get获取数据结果,返回结果是:{}",result);
			JSONObject jsonObject =  JSON.parseObject(result);
			if(jsonObject.getInteger("code")== Constant.SUCCESS_CODE){
				JSONObject obj = new JSONObject();
				obj.put("code",  Constant.SUCCESS_CODE);
				obj.put("msg", ResponseEnum.OK.getMsg());
				obj.put("data",jsonObject.getString("data"));
				if(jsonObject.getInteger("total")!=null){
					obj.put("total",jsonObject.getInteger("total"));
				}
				if(jsonObject.getJSONArray("rows")!=null){
					obj.put("rows",jsonObject.getJSONArray("rows"));
				}
				return obj;
			}else if(jsonObject.getInteger("code")== Constant.WARN){
				return jsonObject;
			}else {
				throw new YamiShopBindException(jsonObject.getString("msg"));
			}
		} catch (YamiShopBindException e){
			throw new YamiShopBindException(e.getMessage());
		} catch (Exception e) {
			if(StrUtil.isNotBlank(e.getMessage()) && (e.getMessage().contains("SocketTimeoutException")||e.getMessage().contains("三方接口超时"))){
				throw new YamiShopBindException("该渠道下游接口超时，请其联系管理员");
			}else{
				e.printStackTrace();
				logger.error("向第三方服务发送数据发生异常",e);
				throw new YamiShopBindException("三方接口异常，请其联系管理员");
			}
		}
	}

	@Override
	public JSONObject hutoolPostWebService(String url, Map<String, String> params,String dtcName,String password) {
		try {
			String paramsStr = JSON.toJSONString(setPostRequestMapParams(params,dtcName,password));
			logger.info("从第三方Post获取数据,请求地址是:{},参数是:{},加密封装后:{}",url,JSONObject.toJSONString(params),paramsStr);
			String result = HttpRequest.post(url).body(paramsStr).setConnectionTimeout(60000).execute().body();
			logger.info("从第三方Post获取数据结果,返回结果是:{}",result);
			JSONObject jsonObject =  JSON.parseObject(result);
			if(jsonObject.getInteger("code")== Constant.SUCCESS_CODE){
				JSONObject obj = new JSONObject();
				obj.put("code",  Constant.SUCCESS_CODE);
				obj.put("msg", ResponseEnum.OK.getMsg());
				obj.put("data",jsonObject.getString("data"));
				if(jsonObject.getInteger("total")!=null){
					obj.put("total",jsonObject.getInteger("total"));
				}
				if(jsonObject.getJSONArray("rows")!=null){
					obj.put("rows",jsonObject.getJSONArray("rows"));
				}
				return obj;
			}else if(jsonObject.getInteger("code")== Constant.WARN){
				return jsonObject;
			}else {
				throw new YamiShopBindException(jsonObject.getString("msg"));
			}
		} catch (YamiShopBindException e){
			throw new YamiShopBindException(e.getMessage());
		} catch (Exception e) {
			if(StrUtil.isNotBlank(e.getMessage()) && (e.getMessage().contains("SocketTimeoutException")||e.getMessage().contains("三方接口超时"))){
				throw new YamiShopBindException("该渠道下游接口超时，请其联系管理员");
			}else{
				e.printStackTrace();
				logger.error("向第三方服务发送数据发生异常",e);
				throw new YamiShopBindException("三方接口异常，请其联系管理员");
			}
		}
	}

	@Override
	public JSONObject hutoolPostObjWebService(String url, Map<String, Object> params,String dtcName,String password) {
		try {
			String paramsStr = setPostObjRequestMapParams(params,dtcName,password);
			logger.info("从第三方Post获取数据,请求地址是:{},参数是:{},加密封装后:{}",url,JSONObject.toJSONString(params),paramsStr);
			String result = HttpRequest.post(url).body(paramsStr).setConnectionTimeout(60000).execute().body();
			logger.info("从第三方Post获取数据结果,返回结果是:{}",result);
			JSONObject jsonObject =  JSON.parseObject(result);
			if(jsonObject.getInteger("code") == Constant.SUCCESS_CODE){
				JSONObject obj = new JSONObject();
				obj.put("code",  Constant.SUCCESS_CODE);
				obj.put("msg", ResponseEnum.OK.getMsg());
				obj.put("data",jsonObject.getString("data"));
				if(jsonObject.getInteger("total")!=null){
					obj.put("total",jsonObject.getInteger("total"));
				}
				if(jsonObject.getJSONArray("rows")!=null){
					obj.put("rows",jsonObject.getJSONArray("rows"));
				}
				return obj;
			}else if(jsonObject.getInteger("code")== Constant.WARN){
				return jsonObject;
			}else {
				throw new YamiShopBindException(jsonObject.getString("msg"));
			}
		} catch (YamiShopBindException e){
			throw new YamiShopBindException(e.getMessage());
		} catch (Exception e) {
			if(StrUtil.isNotBlank(e.getMessage()) && (e.getMessage().contains("SocketTimeoutException")||e.getMessage().contains("三方接口超时"))){
				throw new YamiShopBindException("该渠道下游接口超时，请其联系管理员");
			}else{
				e.printStackTrace();
				logger.error("向第三方服务发送数据发生异常",e);
				throw new YamiShopBindException("三方接口异常，请其联系管理员");
			}
		}
	}


	@SneakyThrows
	public String setGetRequestMapParams(Map<String, String> params,String dtcName,String password) {
		long timestamp = System.currentTimeMillis();
		Map<String,Object> obj = new HashMap<>();
		// 组装参数
		StringBuilder targetUrl = new StringBuilder();
		for (Map.Entry<String, String> entry : params.entrySet()) {
			if(ObjectUtil.isNotEmpty(entry.getValue())){
				obj.put(entry.getKey(),entry.getValue());
				targetUrl.append(entry.getKey()).append("=").append( entry.getValue()).append("&");
			}
		}
		String sign = "";
		if(obj.size()!=0){
			String param = Json.toJsonString(obj);
			logger.info("加密sign前参{},{}",param,StrUtil.isNotEmpty(password)?password:key);
			sign = ParamSignUtil.paramEncode(param, StrUtil.isNotEmpty(password)?password:key);
		}
		targetUrl
				.append("userName").append("=").append(StrUtil.isNotEmpty(dtcName)?dtcName:"dtc").append("&")
				.append("sign").append("=").append(sign).append("&")
				.append("timestamp").append("=").append(String.valueOf(timestamp));
		return targetUrl.toString();

	}
	public String setGetRequestMapParams(String data,Map<String, String> params) {
		long timeStamp = System.currentTimeMillis();
		// 组装参数
		StringBuilder targetUrl = new StringBuilder();
		for (Map.Entry<String, String> entry : params.entrySet()) {
			targetUrl.append(entry.getKey()).append("=").append( entry.getValue()).append("&");
		}
		targetUrl
				.append("userName").append("=").append("dtc").append("&")
				.append("sign").append("=").append(data).append("&")
				.append("timestamp").append("=").append(timeStamp);
		return targetUrl.toString();

	}
	@SneakyThrows
	public Map<String,Object> setPostRequestMapParams(Map<String, String> params,String dtcName,String password) {
		long timestamp = System.currentTimeMillis();
		// 组装参数
		Map<String,Object> obj = new HashMap<>();
		for (Map.Entry<String, String> entry : params.entrySet()) {
			if(ObjectUtil.isNotEmpty(entry.getValue())){
				obj.put(entry.getKey(), entry.getValue());
			}
		}
		String sign = "";
		if(obj.size()!=0){
			String param = Json.toJsonString(obj);
			logger.info("加密sign前参{},{}",param,StrUtil.isNotEmpty(password)?password:key);
			sign = ParamSignUtil.paramEncode(param, StrUtil.isNotEmpty(password)?password:key);
		}
		obj.put("userName",StrUtil.isNotEmpty(dtcName)?dtcName:"dtc");
		obj.put("sign",sign);
		obj.put("timestamp", String.valueOf(timestamp));
		return obj;
	}
	@SneakyThrows
	public String setPostObjRequestMapParams(Map<String, Object> params,String dtcName,String password) {
		long timestamp = System.currentTimeMillis();
		// 组装参数
		Map<String,Object> obj = new HashMap<>();
		for (Map.Entry<String, Object> entry : params.entrySet()) {
			if(ObjectUtil.isNotEmpty(entry.getValue())){
				obj.put(entry.getKey(), entry.getValue());
			}
		}
		String sign = "";
		if(obj.size()!=0){
			String param = Json.toJsonString(obj);
			logger.info("加密sign前参{},{}",param,StrUtil.isNotEmpty(password)?password:key);
			sign = ParamSignUtil.paramEncode(param, StrUtil.isNotEmpty(password)?password:key);
		}
		obj.put("userName",StrUtil.isNotEmpty(dtcName)?dtcName:"dtc");
		obj.put("sign",sign);
		obj.put("timestamp", String.valueOf(timestamp));
		return JSON.toJSONString(obj);
	}
	@SneakyThrows
	public String setPostObjRequestMapParams(List<Object> params,String dtcName,String password) {
		long timestamp = System.currentTimeMillis();
		// 组装参数
		Map<String,Object> obj = new HashMap<>();
		String sign = "";
		if(obj.size()!=0){
			String param = Json.toJsonString(obj);
			sign = ParamSignUtil.paramEncode(param, StrUtil.isNotEmpty(password)?password:key);
		}
		obj.put("userName",StrUtil.isNotEmpty(dtcName)?dtcName:"dtc");
		obj.put("sign",sign);
		obj.put("timestamp", String.valueOf(timestamp));
		return JSON.toJSONString(obj);
	}

	public static void main(String[] args) {
		Map<String,Object> obj = new HashMap<>();
		obj.put("denomName","testNo1");
		obj.put("denomId","testzcq");
		obj.put("chain","dt");
		String param = Json.toJsonString(obj);
		String sign = "";
		try {
			sign = ParamSignUtil.paramEncode(param, "tICWkmPU4s0x28K2");
		} catch (Exception e) {
			e.printStackTrace();
		}
		obj.put("userName","zhangchaoqun");
		obj.put("sign",sign);
		obj.put("timestamp", System.currentTimeMillis());
		String result = HttpRequest.post("https://test-dtc-apigateway.dtchain.net/nft/outapi/api/nftmint/issueDenom")
				.body(JSON.toJSONString(obj)).setConnectionTimeout(60000).execute().body();
		System.out.println(result);
	}

	@Override
	public String hutoolPostWebService(String url, Map<String, String> params) {
		try {
			String paramsStr = JSON.toJSONString(setPostRequestMapParams(params,null,null));
			logger.info("从第三方Post获取数据,请求地址是:{},参数是:{},加密封装后:{}",url,JSONObject.toJSONString(params),paramsStr);
			String result = HttpRequest.post(url).body(paramsStr).setConnectionTimeout(60000).execute().body();
			logger.info("从第三方Post获取数据,返回:{}",result);
			return result;
		} catch (RestClientException e) {
			e.printStackTrace();
			throw new SecurityException("调第三方服务超时");
		}  catch (Exception e) {
			e.printStackTrace();
			logger.error("向第三方服务发送数据发生异常",e);
			throw new YamiShopBindException("三方接口异常");
		}
	}
	@Override
	public String hutoolPostFileWebService(String url, Map<String, String> params, File file) {
		try {
			Map<String, Object> stringObjectMap = setPostRequestMapParams(params, null, null);
			logger.info("从第三方Post获取数据,请求地址是:{},参数是:{},加密封装后:{}",url,JSONObject.toJSONString(params),JSONObject.toJSONString(stringObjectMap));
			String result = HttpRequest.post(url).form(stringObjectMap).header("source","1").header("Content-type","multipart/form-data").form("file",file).setConnectionTimeout(60000).execute().body();
			logger.info("从第三方Post获取数据,返回:{}",result);
			return result;
		} catch (RestClientException e) {
			e.printStackTrace();
			throw new SecurityException("调第三方服务超时");
		}  catch (Exception e) {
			e.printStackTrace();
			logger.error("向第三方服务发送数据发生异常",e);
			throw new YamiShopBindException("三方接口异常");
		}
	}
	@Override
	public String hutoolGetWebService(String url, Map<String, String> params) {
		try {
			String paramsStr = setGetRequestMapParams(params,null,null);
			logger.info("从第三方Post获取数据,请求地址是:{},参数是:{},加密封装后:{}",url,JSONObject.toJSONString(params),paramsStr);
			String result = HttpRequest.get(url+paramsStr).header("source","1").setConnectionTimeout(60000).execute().body();
			logger.info("从第三方Post获取数据,返回:{}",result);
			return result;
		} catch (RestClientException e) {
			e.printStackTrace();
			throw new SecurityException("调第三方服务超时");
		}  catch (Exception e) {
			e.printStackTrace();
			logger.error("向第三方服务发送数据发生异常",e);
			throw new YamiShopBindException("三方接口异常");
		}
	}
	@Override
	public String hutoolPostObjWebService(String url, Map<String, Object> params) {
		try {
			String paramsStr = setPostObjRequestMapParams(params,null,null);
			logger.info("从第三方Post获取数据,请求地址是:{},参数是:{},加密封装后:{}",url,JSONObject.toJSONString(params),paramsStr);
			String result = HttpRequest.post(url).body(paramsStr).setConnectionTimeout(60000).execute().body();
			logger.info("从第三方Post获取数据结果,返回结果是:{}",result);
			return result;
		} catch (RestClientException e) {
			e.printStackTrace();
			throw new SecurityException("调第三方服务超时");
		} catch (Exception e) {
			e.printStackTrace();
			logger.error("向第三方服务发送数据发生异常",e);
			throw new YamiShopBindException("三方接口异常");
		}
	}


	@Override
	public void checkSign(Map<String, Object> jSONObject, Map<String, Object> mapList,String password) {
		for (String key : jSONObject.keySet()) {
			if(!key.equals("userName") && !key.equals("sign") && !key.equals("timestamp") && !ObjectUtil.isNull(jSONObject.get(key))){
				mapList.put(key, jSONObject.get(key));
			}
		}
		try {
			if(!ParamSignUtil.paramEncode( Json.toJsonString(mapList),StrUtil.isNotEmpty(password)?password : key).equals(jSONObject.get("sign"))){
				throw new YamiShopBindException("验签失败");
			}
		} catch (Exception exception) {
			throw new YamiShopBindException("验签失败");
		}
	}

}
